
package com.hlkj.pay.app.merchant.ext.impl.alipay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import com.alipay.api.AlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.AlipayFundAccountbookCreateRequest;
import com.alipay.api.request.AlipayFundAccountbookQueryRequest;
import com.alipay.api.request.AlipayUserAgreementPageSignRequest;
import com.alipay.api.request.AlipayUserAgreementQueryRequest;
import com.alipay.api.response.AlipayFundAccountbookCreateResponse;
import com.alipay.api.response.AlipayFundAccountbookQueryResponse;
import com.alipay.api.response.AlipayUserAgreementPageSignResponse;
import com.alipay.api.response.AlipayUserAgreementQueryResponse;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantAccessExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.access.*;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AliPayAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AlipayConfig;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AlipayFundAccessExtentDto;
import com.hlkj.pay.app.merchant.ext.impl.alipay.handler.AlipayMerchantCommonParamsHandle;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouConfig;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.utils.FuYouCallBackParamsParseUtil;
import com.hlkj.pay.dto.merchant.AccessChannelParamsDto;
import com.hlkj.pay.dto.merchant.MerchantAccessDto;
import com.hlkj.pay.dto.merchant.MerchantAccessSignLink;
import com.hlkj.pay.enums.CommonEnum;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessCertInfoDO;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.vo.order.resp.MerchantProductQueryResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 支付宝安全发进件操作
 * 
 * @author HlpayTeam
 * @date 2024/09/26 10:25
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_ALIPAY_FUND)
public class AlipayFundMerchantAccessExtPt implements ChannelMerchantAccessExtPt {

    private final AlipayMerchantCommonParamsHandle alipayMerchantCommonParamsHandle;

    @Override
    public void channelConfigCheck(ChannelMerchantAccessCommonContext channelMerchantAccessCommonContext) {
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelMerchantAccessCommonContext.getProviderChannelConfig(),
                channelMerchantAccessCommonContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelMerchantAccessCommonContext.setRemark(alipayConfigCommonResult.getMsg());
            channelMerchantAccessCommonContext.setProcessStatus(false);
        }
    }

    @Override
    public void merchantAccess(ChannelMerchantAccessContext channelMerchantAccessContext) {
        log.info("支付宝安全发渠道提交进件 请求参数:{}", JsonUtils.toJsonString(channelMerchantAccessContext));
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelMerchantAccessContext.getProviderChannelConfig(),
                channelMerchantAccessContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(alipayConfigCommonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(false);
            return;
        }
        MerchantAccessDto merchantAccessDto = channelMerchantAccessContext.getMerchantAccessDto();
        MerchantAccessInfoDO merchantAccessInfo = merchantAccessDto.getMerchantAccessInfo();
        if (StringUtils.hasText(merchantAccessInfo.getSubMchId())) {
            log.info("支付宝安全发渠道当前没有更新商户信息直接返回:{}", merchantAccessInfo.getSubMchId());
            return;
        }
        try {
            MerchantAccessCertInfoDO merchantAccessContact = merchantAccessDto.getMerchantAccessContact();
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayUserAgreementPageSignRequest request = new AlipayUserAgreementPageSignRequest();
            AlipayUserAgreementPageSignModel model = new AlipayUserAgreementPageSignModel();
            model.setProductCode("FUND_SAFT_SIGN_WITHHOLDING");
            model.setSignScene("INDUSTRY|SATF_ACC");
            // 设置用户在商户网站的登录账号
            model.setExternalLogonId(merchantAccessContact.getPhone());
            // 设置个人签约产品码
            model.setPersonalProductCode("FUND_SAFT_SIGN_WITHHOLDING_P");
            // 设置商户签约号
            model.setExternalAgreementNo(merchantAccessInfo.getRequestId());
            // 设置请按当前接入的方式进行填充
            AccessParams accessParams = new AccessParams();
            accessParams.setChannel("QRCODE");
            model.setAccessParams(accessParams);
            // 第三方代调用模式下请设置 app_auth_token
            request.setNotifyUrl(channelMerchantAccessContext.getAsyncReturnUrl());
            request.setBizModel(model);
            log.error("支付宝个人协议 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            // AlipayUserAgreementPageSignResponse response =
            // alipayClient.certificateExecute(request, "get");
            AlipayUserAgreementPageSignResponse response = alipayClient.pageExecute(request, "get");
            log.info("支付宝个人协议 返回参数:{}", JsonUtils.toJsonString(response));
            // 如果需要返回GET请求，请使用
            String pageRedirectionData = response.getBody();
            if (response.isSuccess()) {
                // String signParams =
                // response.getBody().replace("https://openapi.alipay.com/gateway.do?","");
                // 生成唤起客户端。把signParams使用 UTF-8 字符集整体做一次 encode
                // String link=
                // "alipays://platformapi/startapp?appId=60000157&appClearTop=false&startMultApp=YES&sign_params="+
                // URLEncoder.encode(signParams);

                MerchantAccessSignLink merchantAccessSignLink = new MerchantAccessSignLink();
                merchantAccessSignLink.setLink(response.getBody());
                merchantAccessSignLink.setName("支付宝个人协议");
                channelMerchantAccessContext.setSignLinks(new ArrayList<>() {

                    {
                        add(merchantAccessSignLink);
                    }
                });
                channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SIGNING);
            }
            else {
                channelMerchantAccessContext.setProcessStatus(false);
                channelMerchantAccessContext.setRemark(response.getSubMsg());
            }
        }
        catch (Exception e) {
            channelMerchantAccessContext.setProcessStatus(false);
            channelMerchantAccessContext.setRemark(e.getMessage());
        }
    }

    @Override
    public String requestUrl(MerchantAccessDto merchantAccessInfoDO) {

        return null;
    }

    @Override
    public String channelParams(AccessChannelParamsDto accessChannelParamsDto) {
        AliPayAppChannelParams params = new AliPayAppChannelParams();
        AlipayFundAccessExtentDto alipayFundAccessExtentDto = JsonUtils.parseObject(accessChannelParamsDto.getExtendA(), AlipayFundAccessExtentDto.class);
        params.setAccountBookId(alipayFundAccessExtentDto.getAccountBookId());
        params.setAgreementNo(accessChannelParamsDto.getSubMchId());
        return JsonUtils.toJsonStringNotNull(params);
    }

    @Override
    public void merchantAccessQuery(ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext) {
    }

    @Override
    public void merchantSign(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {
    }

    @Override
    public void merchantSignQuery(ChannelMerchantAccessSignContext channelMerchantAccessSignContext) {
        // log.info("支付宝安全发渠道签约查询 请求参数:{}",
        // JsonUtils.toJsonString(channelMerchantAccessContext));
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelMerchantAccessSignContext.getProviderChannelConfig(),
                channelMerchantAccessSignContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelMerchantAccessSignContext.setRemark(alipayConfigCommonResult.getMsg());
            channelMerchantAccessSignContext.setProcessStatus(false);
            return;
        }
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessSignContext.getMerchantAccessInfoDO();
        try {
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayUserAgreementQueryRequest request = new AlipayUserAgreementQueryRequest();
            AlipayUserAgreementQueryModel model = new AlipayUserAgreementQueryModel();
            // 设置个人签约产品码
            model.setPersonalProductCode("FUND_SAFT_SIGN_WITHHOLDING_P");
            model.setExternalAgreementNo(merchantAccessInfoDO.getRequestId());
            model.setSignScene("INDUSTRY|SATF_ACC");
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            request.setBizModel(model);
            log.error("支付宝个人协议查询 请求参数:{}", JsonUtils.toJsonStringNotNull(request));
            AlipayUserAgreementQueryResponse response = alipayClient.certificateExecute(request);
            log.info("支付宝个人协议查询 返回参数:{}", JsonUtils.toJsonString(response));
            // 如果需要返回GET请求，请使用
            if (response.isSuccess()) {
                if ("NORMAL".equals(response.getStatus())) {
                    channelMerchantAccessSignContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SET);
                    merchantAccessInfoDO.setSubMchId(response.getAgreementNo());
                }
            }
            else {
                channelMerchantAccessSignContext.setProcessStatus(false);
                channelMerchantAccessSignContext.setRemark(response.getMsg());
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            channelMerchantAccessSignContext.setProcessStatus(false);
            channelMerchantAccessSignContext.setRemark(e.getMessage());
        }
    }

    @Override
    public void merchantBusinessOpen(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // log.info("支付宝安全发渠道签约查询 请求参数:{}",
        // JsonUtils.toJsonString(channelMerchantAccessContext));
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelMerchantBusinessContext.getProviderChannelConfig(),
                channelMerchantBusinessContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelMerchantBusinessContext.setRemark(alipayConfigCommonResult.getMsg());
            channelMerchantBusinessContext.setProcessStatus(false);
            return;
        }
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        try {
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayFundAccountbookCreateRequest request = new AlipayFundAccountbookCreateRequest();
            AlipayFundAccountbookCreateModel model = new AlipayFundAccountbookCreateModel();
            // 设置外部商户系统会员的唯一标识
            model.setMerchantUserId(merchantAccessInfoDO.getSn());
            // 设置外部商户用户类型
            model.setMerchantUserType("BUSINESS_ORGANIZATION");
            // 设置资金记账本的业务场景
            model.setSceneCode("SATF_FUND_BOOK");
            model.setExtInfo("{\"agreement_no\":\""+merchantAccessInfoDO.getSubMchId()+"\"}");
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            log.error("资金记账本开通 请求参数:{}", JsonUtils.toJsonString(request));
            AlipayFundAccountbookCreateResponse response = alipayClient.certificateExecute(request);
            log.error("资金记账本开通 返回参数:{}", JsonUtils.toJsonString(response));
            // 如果需要返回GET请求，请使用
            if (response.isSuccess()) {
                String accountBookId = response.getAccountBookId();
                AlipayFundAccessExtentDto alipayFundAccessExtentDto = new AlipayFundAccessExtentDto();
                alipayFundAccessExtentDto.setAccountBookId(accountBookId);
                ExtCardInfo extCardInfo = response.getExtCardInfo();
                if (extCardInfo != null) {
                    alipayFundAccessExtentDto.setCardNo(extCardInfo.getCardNo());
                    if ("A".equals(extCardInfo.getStatus())) {
                        alipayFundAccessExtentDto.setStatus(CommonEnum.YES_NO_TYPE.YES.getCode());
                    }
                    else {
                        alipayFundAccessExtentDto.setStatus(CommonEnum.YES_NO_TYPE.NO.getCode());
                    }
                    alipayFundAccessExtentDto.setBankAccName(extCardInfo.getBankAccName());
                    alipayFundAccessExtentDto.setCardBranch(extCardInfo.getCardBranch());
                    alipayFundAccessExtentDto.setCardBank(extCardInfo.getCardBank());
                    alipayFundAccessExtentDto.setCardLocation(extCardInfo.getCardLocation());
                    alipayFundAccessExtentDto.setCardDeposit(extCardInfo.getCardDeposit());
                    channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_SUCCESS);
                    channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.FINISH);
                }
                else {
                    channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SETTING);
                    channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTHING);
                }
                merchantAccessInfoDO.setExtendA(JsonUtils.toJsonString(alipayFundAccessExtentDto));
            }
            else {
                channelMerchantBusinessContext.setProcessStatus(false);
                channelMerchantBusinessContext.setRemark(response.getMsg());
            }
        }
        catch (Exception e) {
            channelMerchantBusinessContext.setProcessStatus(false);
            channelMerchantBusinessContext.setRemark(e.getMessage());
        }

    }

    @Override
    public void wechatConfigInit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
    }

    @Override
    public void wechatConfigAdd(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
    }

    @Override
    public void wechatConfigQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {

    }

    @Override
    public void wechatAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        // 微信参数配置
    }

    @Override
    public boolean authConfigQueryType() {
        return true;
    }

    @Override
    public void wechatAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // 文件上传完成就是微信参数自动配置
    }

    @Override
    public void alipayAuthConfig(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
    }

    @Override
    public void alipayAuthQuery(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        // log.info("支付宝安全发渠道签约查询 请求参数:{}",
        CommonResult<AlipayConfig> alipayConfigCommonResult = alipayMerchantCommonParamsHandle.alipayConfig(channelMerchantAccessAuthQueryContext.getProviderChannelConfig(),
                channelMerchantAccessAuthQueryContext.isTest());
        if (!alipayConfigCommonResult.isSuccess()) {
            channelMerchantAccessAuthQueryContext.setRemark(alipayConfigCommonResult.getMsg());
            channelMerchantAccessAuthQueryContext.setProcessStatus(false);
            return;
        }
        MerchantAccessInfoDO merchantAccessInfoDO = channelMerchantAccessAuthQueryContext.getMerchantAccessInfo();
        try {
            AlipayConfig alipayConfig = alipayConfigCommonResult.getData();
            AlipayClient alipayClient = alipayMerchantCommonParamsHandle.initCertificateSdk(alipayConfig);
            // 构造请求参数以调用接口
            AlipayFundAccountbookQueryRequest request = new AlipayFundAccountbookQueryRequest();
            AlipayFundAccountbookQueryModel model = new AlipayFundAccountbookQueryModel();
            // 设置外部商户系统会员的唯一标识
            model.setMerchantUserId(merchantAccessInfoDO.getSn());
            String extendA = merchantAccessInfoDO.getExtendA();
            AlipayFundAccessExtentDto accessExtentDto = JsonUtils.parseObject(extendA, AlipayFundAccessExtentDto.class);
            // 设置外部商户用户类型
            model.setAccountBookId(accessExtentDto.getAccountBookId());
            request.setBizModel(model);
            // 第三方代调用模式下请设置app_auth_token
            // request.putOtherTextParam("app_auth_token", alipayConfig.getAppAuthToken());
            log.error("资金记账本的信息查询 请求参数:{}", JsonUtils.toJsonString(request));
            AlipayFundAccountbookQueryResponse response = alipayClient.certificateExecute(request);
            log.error("资金记账本的信息查询 返回参数:{}", JsonUtils.toJsonString(request));
            // 如果需要返回GET请求，请使用
            if (response.isSuccess()) {
                String accountBookId = response.getAccountBookId();
                AlipayFundAccessExtentDto alipayFundAccessExtentDto = new AlipayFundAccessExtentDto();
                alipayFundAccessExtentDto.setAccountBookId(accountBookId);
                ExtCardInfo extCardInfo = response.getExtCardInfo();
                if (extCardInfo != null) {
                    alipayFundAccessExtentDto.setCardNo(extCardInfo.getCardNo());
                    if ("A".equals(extCardInfo.getStatus())) {
                        alipayFundAccessExtentDto.setStatus(CommonEnum.YES_NO_TYPE.YES.getCode());
                    }
                    else {
                        alipayFundAccessExtentDto.setStatus(CommonEnum.YES_NO_TYPE.NO.getCode());
                    }
                    alipayFundAccessExtentDto.setBankAccName(extCardInfo.getBankAccName());
                    alipayFundAccessExtentDto.setCardBranch(extCardInfo.getCardBranch());
                    alipayFundAccessExtentDto.setCardBank(extCardInfo.getCardBank());
                    alipayFundAccessExtentDto.setCardLocation(extCardInfo.getCardLocation());
                    alipayFundAccessExtentDto.setCardDeposit(extCardInfo.getCardDeposit());
                    channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.FINISH);
                }
                else {
                    channelMerchantAccessAuthQueryContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.ALIPAY_AUTHING);
                }
                merchantAccessInfoDO.setExtendA(JsonUtils.toJsonString(alipayFundAccessExtentDto));
            }
            else {
                channelMerchantAccessAuthQueryContext.setProcessStatus(false);
                channelMerchantAccessAuthQueryContext.setRemark(response.getMsg());
            }
        }
        catch (Exception e) {
            channelMerchantAccessAuthQueryContext.setProcessStatus(false);
            channelMerchantAccessAuthQueryContext.setRemark(e.getMessage());
        }
    }

    @Override
    public MerchantAccessCallBackDto accessCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        MerchantAccessCallBackDto merchantAccessCallBackDto=new MerchantAccessCallBackDto();
        merchantAccessCallBackDto.setRequestId(parameterMap.get("external_agreement_no")[0]);
        merchantAccessCallBackDto.setSubMchId(parameterMap.get("agreement_no")[0]);
        merchantAccessCallBackDto.setAccessStatus(MerchantEnum.ACCESS_STATUS.WAIT_SET);
        return merchantAccessCallBackDto;
    }

    @Override
    public CommonResult<String> accessCallbackParse(String callBackBody, List<ProviderChannelConfigDO> channelConfigDOList) {
        return null;
    }

    @Override
    public MerchantBusinessCallBackDto businessCallBackParamsParse(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        return FuYouCallBackParamsParseUtil.businessCallBackParamsParse(callBackBody);
    }

    @Override
    public boolean verify(String callBackBody, ProviderChannelConfigDO providerChannelConfigDO) {
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        FuYouConfig fuYouConfig = JsonUtils.parseObject(channelConfig, FuYouConfig.class);
        return FuYouCallBackParamsParseUtil.verify(fuYouConfig, callBackBody);
    }

    @Override
    public String callBackResponse(CommonResult commonResult) {
        if (commonResult.isSuccess()) {
            return "SUCCESS";
        }
        else {
            return "FAIL";
        }
    }

    @Override
    public void termAdd(ChannelMerchantTermContext channelMerchantTermContext) {

    }

    @Override
    public void reloadMerchantAuth(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public void channelSplit(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public void productUpdate(ChannelMerchantBusinessContext channelMerchantBusinessContext) {

    }

    @Override
    public Integer queryMerAuthStatus(ChannelMerchantAccessAuthQueryContext channelMerchantAccessAuthQueryContext) {
        return null;
    }

    @Override
    public MerchantProductQueryResp productQuery(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        return null;
    }

    @Override
    public MerchantChannelSplitCallBackDto easySplitCallBackParamsParse(HttpServletRequest request, ProviderChannelConfigDO providerChannelConfigDO) {
        return null;
    }

}
